package pers.cz.common.sharding;


import pers.cz.common.annotation.Rule;
import pers.cz.common.exception.ErrorCode;
import pers.cz.common.exception.OrmException;
import utils.DateUtils;

import java.util.Date;

/**
 * @program: Jef-orm
 * @description: 默认分表计算器
 * @author: Cheng Zhi
 * @create: 2023-11-01 10:00
 **/
public class DefaultShardingStrategy implements IShardingStrategy {

    @Override
    public String getResult(Rule rule, Object value) {
        return calculate(rule.strategy(), rule.modulus(), value);
    }

    @Override
    public String getResult(ShardingStrategy shardingStrategy, Object value) {

        return calculate(shardingStrategy, null, value);
    }

    @Override
    public String getResult(ShardingStrategy shardingStrategy, String modulus, Object value) {
        return calculate(shardingStrategy, modulus, value);
    }

    private String calculate(ShardingStrategy shardingStrategy, String modulus, Object value) {
        switch (shardingStrategy) {
            case DAY:
                return formatDate(value).substring(6,8);
            case MONTH:
                return formatDate(value).substring(4,6);
            case YEAR:
                return formatDate(value).substring(0,4);
            case YEAR_MONTH:
                return formatDate(value).substring(0,6);
            case YEAR_MONTH_DAY:
                return formatDate(value).substring(0,8);
            case MODULUS:
                return calculateModulus(modulus, value);
            default:
                throw new OrmException(ErrorCode.ORM_UNSUPPORTED_SHARDING_STRATEGY, shardingStrategy);
        }
    }
    /**
     * 格式化日期
     * @param value
     * @return
     */
    private String formatDate(Object value) {

        if (value instanceof Date) {
            String yyyyMMddHHmmss = DateUtils.format((Date) value, "yyyyMMddHHmmss");
            return yyyyMMddHHmmss;
        }

        return String.valueOf(value);
    }

    /**
     * 取余运算
     * @return
     */
    private String calculateModulus(String modulus, Object value) {

        String result = "";
        if (value instanceof Long) {
            return String.valueOf((Long)value%Long.valueOf(modulus));
        }

        if (value instanceof Integer) {
            return String.valueOf((Integer)value%Integer.valueOf(modulus));
        }

        if (value instanceof String) {
            try {
                return String.valueOf(Long.valueOf((String) value)%Long.valueOf(modulus));
            } catch (Exception e) {
                throw new OrmException(ErrorCode.ORM_SHARDING_ERROR, value);
            }
        }

        throw new OrmException(ErrorCode.ORM_SHARDING_KEY_ERROR, value);
    }
}
